package com.asiainfo.ai.data.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.util.List;
import java.util.Objects;

/**
 * @author adward
 */
@Slf4j
public class WriteExcel {

    private static final String EXCEL_XLS = "xls";
    private static final String EXCEL_XLSX = "xlsx";

    public WriteExcel() {
    }

    public static void writeExcel(List<List<String>> dataList, String finalXlsxPath) {
        OutputStream out = null;
        Workbook workBook = null;
        try {
            // 读取Excel文档
            File finalXlsxFile = new File(finalXlsxPath);
            //fixbug: [PRDAI_ISSUE_722] 问题修复：Workbook资源未关闭
            workBook = getWorkbook(finalXlsxFile);
            if (Objects.isNull(workBook)) {
                log.error("workBook对象为空");
                return;
            }
            // sheet 对应一个工作页
            Sheet sheet = workBook.getSheetAt(0);

            // 删除原有数据，除了属性列
            int rowNumber = sheet.getLastRowNum();
            for (int i = 1; i <= rowNumber; i++) {
                Row row = sheet.getRow(i);
                sheet.removeRow(row);
            }
            // 创建文件输出流，输出电子表格：这个必须有，否则你在sheet上做的任何操作都不会有效
            out = new FileOutputStream(finalXlsxPath);
            workBook.write(out);
            /**
             * 往Excel中写新数据
             */
            for (int j = 0; j < dataList.size(); j++) {
                // 创建一行：从第二行开始，跳过属性列
                Row row = sheet.createRow(j + 1);
                // 得到要插入的每一条记录
                List<String> dataStr = dataList.get(j);
                for (int k = 0; k < dataStr.size(); k++) {
                    Cell first = row.createCell(k);
                    first.setCellValue(dataStr.get(k));
                }
            }
            // 创建文件输出流，准备输出电子表格：这个必须有，否则你在sheet上做的任何操作都不会有效
            out = new FileOutputStream(finalXlsxPath);
            workBook.write(out);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("errorInfo: {}", e.getMessage());
        } finally {
            try {
                if (out != null) {
                    out.flush();
                    out.close();
                }
                if (workBook != null) {
                    workBook.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage(), e);
                log.error("errorInfo: {}", e.getMessage());
            }
        }
    }


    public static Workbook getWorkbook(File file) throws Exception{
        Workbook wb = null;
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            if (file.getName().endsWith(EXCEL_XLS)) {
                // Excel 2003
                wb = new HSSFWorkbook(in);
            } else if (file.getName().endsWith(EXCEL_XLSX)) {
                // Excel 2007/2010
                wb = new XSSFWorkbook(in);
            }
            in.close();
        } catch (Exception e) {
            log.error("getWorkbok error: {}", e.getMessage());
            log.error(e.getMessage(), e);
            throw e;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error("getWorkbok error: ", e);
            }
        }
        return wb;
    }

}